#include <QDebug>
#include <QSettings>
#include <QApplication>
#include <QDir>
#include "Theme.h"

Theme::Theme(const QString & set, QObject *parent) :
    QObject(parent),
    _set(set),
    _currentLexer("")
{
    _defaultChunk.background = Qt::white;
    _defaultChunk.foreground = Qt::black;
    _defaultChunk.bold = false;
    _defaultChunk.italic = false;
    _defaultChunk.marginBackground = Qt::white;
    _defaultChunk.marginForeground = Qt::black;
    _defaultChunk.selectBackground = Qt::yellow;
    _defaultChunk.selectForeground = Qt::black;
    _defaultChunk.marginSelectForeground = Qt::black;

    _map["Common"]["def"] = _defaultChunk;

    //QSettings pdefault(QApplication::applicationDirPath()+QDir::separator()+"defaulttheme.conf", QSettings::IniFormat);
    //readConf(pdefault);
    QSettings pset(_set, QSettings::IniFormat);
    readConf(pset);
}

void Theme::readConf(QSettings & set)
{
    foreach(QString lexer, set.childGroups()){
        set.beginGroup(lexer);
        if (lexer == "Common"){
            foreach(QString key, set.childKeys()){
                if (key == "background")
                    _map[lexer]["def"].background = set.value(key).toString() != "" ? QColor(set.value(key).toString()) : Qt::white;
                if (key == "selectForeground")
                    _map[lexer]["def"].selectForeground = set.value(key).toString() != "" ? QColor(set.value(key).toString()) : Qt::black;
                if (key == "selectBackground")
                    _map[lexer]["def"].selectBackground = set.value(key).toString() != "" ? QColor(set.value(key).toString()) : Qt::yellow;
                if (key == "marginBackground")
                    _map[lexer]["def"].marginBackground = set.value(key).toString() != "" ? QColor(set.value(key).toString()) : Qt::white;
                if (key == "marginForeground")
                    _map[lexer]["def"].marginForeground = set.value(key).toString() != "" ? QColor(set.value(key).toString()) : Qt::black;
                if (key == "marginSelectForeground")
                    _map[lexer]["def"].marginSelectForeground = set.value(key).toString() != "" ? QColor(set.value(key).toString()) : Qt::black;
            }
        } else {
            foreach(QString key, set.childGroups()){
                set.beginGroup(key);
                foreach(QString subkey, set.childKeys()){
                    if (subkey == "foreground")
                        _map[lexer][key].foreground = set.value(subkey).toString() != "" ? QColor(set.value(subkey).toString()) : Qt::black;
                    if (subkey == "bold")
                        _map[lexer][key].bold = set.value(subkey).toBool();
                    if (subkey == "italic")
                        _map[lexer][key].italic = set.value(subkey).toBool();
                }
                set.endGroup();
            }
        }
        set.endGroup();
    }
}

Theme::Theme(const Theme & theme):
    QObject(theme.parent())
{
    _set = theme._set;
    _currentLexer = theme._currentLexer;
    _map = theme._map;
    _defaultChunk = theme._defaultChunk;
}

Theme::~Theme()
{
}

void Theme::setLexer(const QString & lexerName)
{
    _currentLexer = lexerName;

}

// ***************************************************

QColor Theme::foreground(const QString & key, QColor defColor)
{
    if (_map[_currentLexer].contains(key))
        return _map[_currentLexer].value(key).foreground;
    return defColor;
}

void Theme::setForeground(const QString & key, QColor color)
{
    _map[_currentLexer][key].foreground = color;
}

bool Theme::bold(const QString & key)
{
    return _map[_currentLexer].value(key, _defaultChunk).bold;
}

void Theme::setBold(const QString & key, bool isBold)
{
    _map[_currentLexer][key].bold = isBold;
}

bool Theme::italic(const QString & key)
{
    return _map[_currentLexer].value(key, _defaultChunk).italic;
}

void Theme::setItalic(const QString & key, bool isItalic)
{
    _map[_currentLexer][key].italic = isItalic;
}

// ***************************************************

QColor Theme::selectForeground()
{
    return _map["Common"].value("def", _defaultChunk).selectForeground;
}

void Theme::setSelectForeground(QColor color)
{
    _map["Common"]["def"].selectForeground = color;
}

QColor Theme::background()
{
    return _map["Common"].value("def", _defaultChunk).background;
}

void Theme::setBackground(QColor color)
{
    _map["Common"]["def"].background = color;
}

QColor Theme::selectBackground()
{
    return _map["Common"].value("def", _defaultChunk).selectBackground;
}

void Theme::setSelectBackground(QColor color)
{
    _map["Common"]["def"].selectBackground = color;
}

QColor Theme::marginBackground()
{
    return _map["Common"]["def"].marginBackground;
}

void Theme::setMarginBackground(QColor color)
{
    _map["Common"]["def"].marginBackground = color;
}

QColor Theme::marginForeground()
{
    return _map["Common"]["def"].marginForeground;
}

void Theme::setMarginForeground(QColor color)
{
    _map["Common"]["def"].marginForeground = color;
}

QColor Theme::marginSelectForeground()
{
    return _map["Common"]["def"].marginSelectForeground;
}

void Theme::setMarginSelectForeground(QColor color)
{
    _map["Common"]["def"].marginSelectForeground = color;
}


bool Theme::save()
{
    qDebug() << "Save theme" << _set;
    QSettings set(_set, QSettings::IniFormat);

    set.setValue("Common/background", background().name());
    set.setValue("Common/selectForeground", selectForeground().name());
    set.setValue("Common/selectBackground", selectBackground().name());
    set.setValue("Common/marginBackground", marginBackground().name());
    set.setValue("Common/marginForeground", marginForeground().name());
    set.setValue("Common/marginSelectForeground", marginSelectForeground().name());


    QMap<QString, QMap<QString, ThemeChunk> >::const_iterator it = _map.constBegin();
    while (it != _map.constEnd()){
        if (it.key() != "Common"){
            set.beginGroup(it.key());
            QMap<QString, ThemeChunk>::const_iterator sit = it.value().constBegin();
            while (sit != it.value().constEnd()){
                set.beginGroup(sit.key());
                setColor(set, "foreground", sit.value().foreground);
                set.setValue("bold", sit.value().bold);
                set.setValue("italic", sit.value().italic);
                set.endGroup();
                ++sit;
            }
            set.endGroup();
        }
        ++it;
    }
    return false;
}

void Theme::setColor(QSettings& set, const QString & key, QColor color)
{
    if (color.isValid() && color != Qt::transparent)
        set.setValue(key, color.name());
    else
        set.setValue(key, "");
}


